package com.blackline.auto.Account;

import static org.junit.Assert.fail;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

import com.blackline.declareUI.UI;
import com.blackline.parameters.Parameters;
import com.blackline.parameters.TestData;
import com.blackline.auto.common.*;

/**
 * @author XBO
 * @version Feb, 2013
 * <p>The smoke test to Account module.
 */
public class Account_smoketest {
	
	private WebDriver driver;
	private StringBuffer verificationErrors = new StringBuffer();
	private static Logger logger=Logger.getLogger(Account_smoketest.class);
	UI UI=new UI();
	Parameters parameters;
	@Before
	public void setUp() throws Exception {
		FirefoxProfile profile=new FirefoxProfile();
		profile.setEnableNativeEvents(true);
		parameters=new Parameters("parameters.xml");

		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		UI.declareAllUI(driver);
	}
	
	@SuppressWarnings("static-access")
	@Test
	public void Accountsmoketest() throws Exception {
		TestData testdata=new TestData("TestData/Account_smoketest.xml");

	//=======================Data Preparation=======================//
		//Generate current time string, and write into Account.Import.txt later
		SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMdd-kk-mm-ss");
		Date date = new Date();
		
		String dateString = sdf.format(date);
		logger.info("Current time is: " + dateString);
		
		//The last field of following inputText is "8900"
		String inputText = "4000	"+ dateString +"									A2013022601	A2013022601	A	Asset	TRUE	TRUE	USD	USD	1/31/2011			8900";
		logger.info("The inputText for " + testdata.getInput("accountFile") + " is: " + inputText);
		//Create Account.Import.text file and write inputText into it.
		CommonMethods cm = new CommonMethods();
		cm.createFile(("TestData\\" + testdata.getInput("accountFile")), inputText);
		
		//The absolute path of the Account.Import.Auto01.txt file.
		String accountFilePath = System.getProperty("user.dir") + "\\TestData\\" + testdata.getInput("accountFile");
		logger.info("Location of " + testdata.getInput("accountFile") + " is: " + accountFilePath);
		
		//Account file without extension: Account.Import.Auto01.txt > Account.Import.Auto01
		String inputFileNoExtension = testdata.getInput("accountFile").substring(0, testdata.getInput("accountFile").length()-4);
		logger.info("Account file without extension is: " + inputFileNoExtension);
	
	//=======================Import Account=======================//
		//Log into system
		UI.LogonPage.Login(driver, parameters.urlDev3, parameters.getLogonID("admin"), parameters.getPassword("admin"));
		UI.NavigationMenu.IMPORTS.click();
		UI.NavigationMenu.Import_Data.click();
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Import Data from a file"));
		UI.page.selectOptionForDropdownList(UI.ImportData.Import_dropDownList, "Accounts");
		UI.ImportData.Document_textField.sendKeys(accountFilePath);
		UI.ImportData.Import_button.click();
		if (UI.ImportData.OperationResult.getText().contains("Succeed"))
		{
			logger.info("[Pass!] The importing file operation succeeded!");
		}
		else
		{
			logger.error("[Fail!] The importing file operation failed!");
			verificationErrors.append("[Fail!] The importing file operation failed!");
		}
		UI.NavigationMenu.REPORTS.click();
		UI.NavigationMenu.IMPORTS.click();
		UI.NavigationMenu.Import_Status.click();
		UI.ImportStatus.Process_Name_filterField.sendKeys(inputFileNoExtension);
		UI.ImportStatus.Process_Name_filterField.sendKeys(Keys.ENTER);
		
		//System need sometime to complete the status update. So sleep 20 seconds, then Refresh.
		Thread.sleep(20000);
		UI.ImportStatus.Refresh_button.click();

		
		String Status1 = UI.ImportStatus.Status_of1stSearchedResult.getText();
		String Successful1 = UI.ImportStatus.Successful_of1stSearchedResult.getText();
		String Status2 = UI.ImportStatus.Status_of2ndSearchedResult.getText();
		String Successful2 = UI.ImportStatus.Successful_of2ndSearchedResult.getText();
		String Status3 = UI.ImportStatus.Status_of3rdSearchedResult.getText();
		String Successful3 = UI.ImportStatus.Successful_of3rdSearchedResult.getText();
		
		
		logger.info("Status of item 1 is: " + Status1 + ", and Success of item 1 is: " + Successful1);
		logger.info("Status of item 2 is: " + Status2 + ", and Success of item 2 is: " + Successful2);
		logger.info("Status of item 3 is: " + Status3 + ", and Success of item 3 is: " + Successful3);

		if (Status1.equals("Finished") && Successful1.equals("Yes") && Status2.equals("Finished") && Successful2.equals("Yes") && Status3.equals("Finished") && Successful3.equals("Yes"))
		{
			logger.info("Status of first 3 records are 'Finished' and successfully fields are 'yes'");
		}
		else
		{
			logger.error("[Failed!] At least one status or successful is worng.");
			verificationErrors.append("[Failed!] At least one status or successful is worng.");
		}
		UI.NavigationMenu.ACCOUNTS.click();
		UI.NavigationMenu.View_Reconciliations.click();
		UI.SessionMenu.DownArrow_Periods.click();
		UI.SessionMenu.selectDate(driver, "1/31/2011");

		Thread.sleep(15000);
		
//		UI.Accounts_viewReconciliations.Account_textField.sendKeys("20130226-11-25-04");//Use this for debug.
		UI.Accounts_viewReconciliations.Account_textField.sendKeys(dateString);
		UI.Accounts_viewReconciliations.Refresh_icon.click();
		Thread.sleep(15000);
		if (UI.Accounts_viewReconciliations.View.getText().equals("View"))
		{
			logger.info("Account '" + dateString + "' exists.");
		}
		else{
			logger.error("Can NOT find account: " + dateString);
			verificationErrors.append("Can NOT find account: " + dateString);
		}
		
	//=======================Assign Roles=======================//	
		UI.NavigationMenu.REPORTS.click();
		UI.NavigationMenu.ACCOUNTS.click();
		UI.NavigationMenu.Accounts.click();
//		UI.page.VerifyPageTitle(driver, "Accounts");
		UI.Accounts.Account_textField.sendKeys(dateString);
		UI.Accounts.Apply_link.click();
		UI.Accounts.Edit_iconOf1stResearchedResult.click();
		//Strange, Assignment Page's title is 'Accounts'
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Accounts"));
		
		//To display "Reviewer" text field, must check on "Dual Level Review Required" checkbox.
		if (!UI.AssignmentPage_Accounts.Dual_Level_Review_Required_checkbox.isSelected())
		{
			UI.AssignmentPage_Accounts.Dual_Level_Review_Required_checkbox.click();
			Thread.sleep(10000);
		}
		//Assign roles
		UI.AssignmentPage_Accounts.Preparer_textField.sendKeys(parameters.getFullName("preparer"));
		Thread.sleep(2000);
		UI.AssignmentPage_Accounts.Copyright_text.click();
		UI.AssignmentPage_Accounts.Approver_textField.sendKeys(parameters.getFullName("approver"));
		Thread.sleep(2000);
		UI.AssignmentPage_Accounts.Copyright_text.click();
		UI.AssignmentPage_Accounts.Reviewer_textField.sendKeys(parameters.getFullName("reviewer"));
		Thread.sleep(2000);
		UI.AssignmentPage_Accounts.Copyright_text.click();
		UI.AssignmentPage_Accounts.Account_Reviewer_textField.sendKeys(parameters.getFullName("ar"));
		Thread.sleep(2000);
		UI.AssignmentPage_Accounts.Copyright_text.click();
		UI.AssignmentPage_Accounts.Account_Manager_textField.sendKeys(parameters.getFullName("am"));
		Thread.sleep(2000);
		UI.AssignmentPage_Accounts.Copyright_text.click();
		UI.AssignmentPage_Accounts.Internal_Auditor_textField.sendKeys(parameters.getFullName("ia"));
		Thread.sleep(2000);
		UI.AssignmentPage_Accounts.Copyright_text.click();
		UI.AssignmentPage_Accounts.Save_button.click();
		Thread.sleep(2000);
		
		UI.Accounts.Account_textField.clear();
		UI.Accounts.Account_textField.sendKeys(dateString);
		UI.Accounts.Account_textField.sendKeys(Keys.ENTER);
		
		
		//Check the preparer of searched result
		String assignedUser = UI.Accounts.Preparer_of1stSearchedResult.getText();
		if (testdata.getInput("expectedPreparer").equals(assignedUser))
		{
			logger.info("[Pass!] The assigned user is as expected: " + testdata.getInput("expectedPreparer"));
		}
		else
		{
			logger.error("[Fail!] The assigned user is NOT as expected '" + testdata.getInput("expectedPreparer") + "', but is: " + assignedUser);
			verificationErrors.append("[Fail!] The assigned user is NOT as expected '" + testdata.getInput("expectedPreparer") + "', but is: " + assignedUser);
		}
		
		UI.SessionMenu.LogOut.click();
		
		
	//=======================Certify by preparer=======================//
		//Login as Preparer(xbopre)
		UI.LogonPage.Login(driver, parameters.urlDev3, parameters.getLogonID("preparer"), parameters.getPassword("preparer"));
		//Verify role "Preparer" text exists
			if ("PREPARER".equals(UI.SessionMenu.Role.getText()))
					{
						logger.info("[Pass!] The text of the role is: PREPARER");
					}
			else
			{
				logger.error("[Fail!] The text of the role is NOT: PREPARER");
				verificationErrors.append("[Fail!] The text of the role is NOT: PREPARER");
			}
		
		//Select correct period
		UI.NavigationMenu.ACCOUNTS.click();
		UI.SessionMenu.DownArrow_Periods.click();
		Thread.sleep(2000);
		UI.SessionMenu.selectDate(driver, "1/31/2011");
		Thread.sleep(5000);
		
		//Search account
//		UI.Accounts_ExceGrid.Account_textField.sendKeys("20130226-11-25-04");//Use this for debug.
		UI.Accounts_ExceGrid.Account_textField.clear();
		UI.Accounts_ExceGrid.Account_textField.sendKeys(dateString); //Use this one in final script!!!!!!
		UI.Accounts_ExceGrid.Refresh_button.click();
		Thread.sleep(3000);
		
		UI.Accounts_ExceGrid.Edit_linkOf1stSearchedResult.click();
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Reconciliation"));
		
		//Add supporting item
		UI.Reconciliation.Add_Supporting_Item_link.click();
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Add Item"));
		UI.AddItem.Txn_Amount_textField.sendKeys(testdata.getInput("addItemAmount"));
		UI.AddItem.List_Component_radioButton.click();
		
		
		//Input texts into Description text box. To do this, need switch to the Description iFrame first.
		String idofDescriptionIframe = UI.AddItem.Description_iframe.getAttribute("id");
		driver.switchTo().frame(idofDescriptionIframe);
		UI.AddItem.Description_textBox.sendKeys(testdata.getInput("description"));
		//Switch back to default content
		driver.switchTo().defaultContent();
		
		UI.AddItem.Add_Comment_link.click();
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Add Item"));
		
		//Input texts into Comment text box. To do this, need switch to the Description Comment first.
		String idofCommentIframe = UI.CommentDetails.Comment_iframe.getAttribute("id");
		driver.switchTo().frame(idofCommentIframe);
		UI.CommentDetails.Comment_textBox.sendKeys(testdata.getInput("comment"));
		//Switch back to default content
		driver.switchTo().defaultContent();
		
		UI.CommentDetails.Save_button.click();
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Add Item"));
		
		//Check whether newly added comment exists.
		if (!"".equals(UI.AddItem.Texts_of1stComment.getText()))
		{
			logger.info("Comment is added.");
		}
		else
		{
			logger.error("[Fail!] Can NOT find comment.");
			verificationErrors.append("[Fail!] Can NOT find comment.");
		}
		
		//Click Add Document link
		UI.AddItem.Add_Document_link.click();
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Add Item"));
		//Input a document path
		UI.DocumentDetails.Document_textField.sendKeys(accountFilePath);//!!!!!!!!!!! Use this in final script.
//		UI.DocumentDetails.Document_textField.sendKeys("D:\\EclipseWorkspace2\\BlackLineSmokeTestwithUI\\TestData\\Account.Import.Auto03.txt");//!!!!!!! For debug only. Remove in final script
		
		
		//Input texts into Description text box. To do this, need switch to the Description iFrame first.
		String idofDocumentIframe = UI.DocumentDetails.Description_iframe.getAttribute("id");
		driver.switchTo().frame(idofDocumentIframe);
		UI.DocumentDetails.Description_textBox.sendKeys(testdata.getInput("documentDesc"));
		//Switch back to default content
		driver.switchTo().defaultContent();
		
		UI.DocumentDetails.Save_button.click();
		Thread.sleep(5000);
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Add Item"));
		
		//Check whether newly added document exists.
		if (!"".equals(UI.AddItem.Texts_of1stDocument.getText()))
		{
			logger.info("Document is added.");
		}
		else
		{
			logger.error("[Fail!] Can NOT find the document.");
			verificationErrors.append("[Fail!] Can NOT find the document.");
		}
		
		UI.AddItem.Save_button.click();	
		
		//Verify a new item shows under "Supporting Items" table.
		if (UI.Reconciliation.Document_iconOf1stSupportingItem != null)
		{
			logger.info("New item shows under Supporting Items table.");
		}
		else
		{
			logger.error("[Fail!] Can NOT find the new item under Supprting Item table.");
			verificationErrors.append("[Fail!] Can NOT find the new item under Supprting Item table.");
		}
		
		//Verify Certify button is enabled.
		if (UI.Reconciliation.Certify_button.isEnabled())
		{
			logger.info("Certify button is enabled.");
			UI.Reconciliation.Certify_button.click();
			UI.Certify.Certify_button.click();
		}
		else
		{
			logger.error("Certify button is NOT enabled.");
			verificationErrors.append("Certify button is NOT enabled.");
//			UI.Reconciliation.Cancel_button.click();
		}
		
		
		//Redirect to Accounts page
//		verificationErrors.append(UI.page.VerifyPageTitle(driver, "Accounts"));
		
//		UI.Accounts_ExceGrid.Account_textField.sendKeys("20130226-11-25-04");//Use this for debug.
		UI.Accounts_ExceGrid.Account_textField.clear();
		UI.Accounts_ExceGrid.Account_textField.sendKeys(dateString); //Use this one in final script!!!!!!
		UI.Accounts_ExceGrid.Refresh_button.click();
		
		//Verify the Account status change from "Edit" to "View"
		if ("View".equals(UI.Accounts_ExceGrid.View_linkOf1stSearchedResult.getText()))
		{
			logger.info("[Pass!] The status is : View, not 'Edit' anymore.");
		}
		else
		{
			logger.error("[Fail!] The status should be 'View', but not.");
			verificationErrors.append("[Fail!] The status should be 'View', but not.");
		}
		
		//Verify the symbol "√P" shows.
		if(UI.Accounts_ExceGrid.Prepared_icon != null)
		{
			logger.info("[Pass!] Prepared icon exists.");
		}
		else
		{
			logger.error("[Fail!] Prepared icon does NOT exists.");
			verificationErrors.append("[Fail!] Prepared icon does NOT exists.");
		}
		
		UI.SessionMenu.LogOut.click();
		
	//=======================Reject by approver=======================//
		UI.LogonPage.Login(driver, parameters.urlDev3, parameters.getLogonID("approver"), parameters.getPassword("approver"));
		UI.SessionMenu.DownArrow_Periods.click();
		Thread.sleep(2000);
		UI.SessionMenu.selectDate(driver, "1/31/2011");
		//==============================//
		Thread.sleep(5000);//==========Do NOT DELETE!!!!!!!!!!!!!! Without this sleep, after select date, it will directly
		//Go to next step without the page really refreshed.
		//==============================//
		UI.NavigationMenu.ACCOUNTS.click();
		//==============================//
		Thread.sleep(10000);//==========Do NOT DELETE!!!!!!!!!!!!!! Without this sleep, after clicking Account, it will directly
		//input data string into Account_textField without waiting the whole page refreshed out.
		//==============================//
		//Filter the account
//		UI.Accounts_ExceGrid.Account_textField.sendKeys("20130306-08-44-43");//Use this for debug.
		UI.Accounts_ExceGrid.Account_textField.sendKeys(dateString); //Use this one in final script!!!!!!
		UI.Accounts_ExceGrid.Refresh_button.click();
		
		UI.Accounts_ExceGrid.Cert_icon.click();

		UI.Reconciliation.Add_Comment_link.click();
		
		//Input texts into comments text box. To do this, need switch to the Comments iFrame first.
		String idofIframe = UI.Comments.Comment_iframe.getAttribute("id");
		driver.switchTo().frame(idofIframe);
		UI.Comments.Comment_textBox.sendKeys(testdata.getInput("commentByApprover"));
		//Switch back to default content
		driver.switchTo().defaultContent();
		UI.Comments.Save_button.click();
		
		//Verify the comment added successfully.
		if (UI.Reconciliation.Texts_of1stComment != null)
		{
			logger.info("[Pass!] Comment added successfully.");
		}
		else
		{
			logger.error("[Fail!] Can NOT find new comment.");
			verificationErrors.append("[Fail!] Can NOT find new comment.");
		}
		
		//Click Add Document link
		UI.Reconciliation.Add_Document_link.click();
		
		UI.Document.Document_textField.sendKeys(accountFilePath);
		UI.Document.Save_button.click();
		
		//Verify document uploaded successfully.
		if (UI.Reconciliation.Document_Name_of1stSupportingDocument != null)
		{
			logger.info("[Pass!] Document is uploaded");
		}
		else
		{
			logger.error("[Fail!] Document is NOT uploaded successfully.");
			verificationErrors.append("[Fail!] Document is NOT uploaded successfully.");
		}
		
		UI.Reconciliation.Reject_button.click();
		
		//======================Handle the popped-up Send Notification window========================//
		String currentWindow = driver.getWindowHandle();
		String currentWindowBak = currentWindow;//backup the handle of current window to be used in future.
		Set<String> handles = driver.getWindowHandles();
		Iterator<String> it = handles.iterator();
        while(it.hasNext()){
        	if (currentWindow == it.next()) continue;
        	WebDriver window = driver.switchTo().window(it.next());
        	logger.info("Title of current window: " + window.getTitle()+", URL is: " + window.getCurrentUrl());
        }

        UI.SendNotificationofRejection.Send_Button.click();
        
        WebDriver windowBack = driver.switchTo().window(currentWindowBak);//Back to previous window.
        logger.info("Title of current window: " + windowBack.getTitle()+", URL is: " + windowBack.getCurrentUrl());
        
//		UI.Accounts_ExceGrid.Account_textField.sendKeys("20130226-11-25-04");//Use this for debug.
		UI.Accounts_ExceGrid.Account_textField.sendKeys(dateString); //Use this one in final script!!!!!!
		UI.Accounts_ExceGrid.Refresh_button.click();
		
		//Check 'Rej' status
		if (UI.Accounts_ExceGrid.Rej_icon != null)
		{
			logger.info("[Pass!] Status is 'Rej'");
		}
		else
		{
			logger.error("[Fail!] Status is NOT 'Rej'");
			verificationErrors.append("[Fail!] Status is NOT 'Rej'");
		}
		
		//Remove temp file
		cm.deleteFile(("TestData\\" + testdata.getInput("accountFile")));
		
	}
	
	
	
	@After
	public void tearDown() throws Exception {
		CommonMethods.takeScreenShot(this.getClass(), driver);
 		driver.close();
 		driver.quit();
		String verificationErrorString = verificationErrors.toString();
		if (!"".equals(verificationErrorString)) {
			fail(verificationErrorString);
		}
	}
	
}
